package zhizhemodi.tech.short_term_bwork.tool;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import zhizhemodi.tech.short_term_bwork.controller.WebSocketServer;
import zhizhemodi.tech.short_term_bwork.entity.Plan;
import zhizhemodi.tech.short_term_bwork.mapper.PlanMapper;
import zhizhemodi.tech.short_term_bwork.mapper.ProgramMapper;
import zhizhemodi.tech.short_term_bwork.service.PlanToDeviceService;
import zhizhemodi.tech.short_term_bwork.service.ProgramService;

@Component
@EnableScheduling
public class ScheduleWork {

    public static final String Key_Plan = "plan";
    public static final String Key_Value = "value";
    public static final String Key_List = "list";

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    PlanMapper planMapper;

    @Autowired
    ProgramMapper programMapper;

    @Autowired
    WebSocketServer webSocketServer;

    @Resource
    ProgramService programService;

    @Resource
    PlanToDeviceService planToDeviceService;

    List<littlePlan> planList = new ArrayList<>();

    @Getter
    @Setter
    @AllArgsConstructor
    class littlePlan{
        Integer planId;
        Timestamp startTime;
        Timestamp endTime;
        List<Integer> deviceList;
        Boolean planState;
    }

    /**
     * 定时任务1
     * 用于生成发送的消息体
     * 并缓存数据到redis
     */
    @Scheduled(cron = "0/10 * * * * *")
    public void addPlanByStartIn10Mins() {
        List<Plan> plans = planMapper.getStartInNextXmins(-600);
        for(Plan plan : plans) {
            try{
                planList.add(planList.size(), new littlePlan(plan.getPlanId(), plan.getStartDatetime(), plan.getEndDatetime(), planToDeviceService.getDeviceListByPlanId(plan.getPlanId()), false));
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", "plan");
                jsonObject.put("program", programService.getMsgByPlanId(plan.getPlanId()));
                jsonObject.put("planId", plan.getPlanId());
                redisTemplate.opsForValue().set(String.valueOf(plan.getPlanId()), jsonObject.toJSONString());
                plan.setPublishState("发布中");
                planMapper.updateById(plan);
            } catch(Exception e) {
                System.out.println(e.getMessage());
                for(littlePlan lPlan : planList) {
                    if(lPlan.getPlanId() == plan.getPlanId()){
                        planList.remove(lPlan);
                        break;
                    }
                }
            }
        }
    }

    /**
     * 定时任务2
     * 用于向客户端发送计划
     */
    @Scheduled(cron = "0/2 * * * * *")
    public void pubPlanByStartNow() {
        try {
            List<Integer> pList = webSocketServer.getConfirmList();
            for(int i = 0;i < planList.size();i++) {
                if(pList.contains(planList.get(i).getPlanId())) setPlanState(planList.get(i).getPlanId());
                if(planList.get(i).getPlanState() == false && planList.get(i).getStartTime().before(new Timestamp(System.currentTimeMillis()))) {
                    String msg = String.valueOf(redisTemplate.opsForValue().get(String.valueOf(planList.get(i).getPlanId())));
                    for(Integer deviceId : planList.get(i).getDeviceList()) { 
                        WebSocketServer.sendMessage(msg, deviceId);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
        }
    }

    @Scheduled(cron = "0 0/8 * * * *")
    public void deletePlanByStartIn10Mins() {
        try{
            for(int i = 0;i < planList.size();i++) {
                if(planList.get(i).getEndTime().before(new Timestamp(System.currentTimeMillis()))){
                    planList.remove(i);
                    i--;
                }
            }
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public void setPlanState(Integer planId) {
        for(littlePlan lPlan : planList) {
            if(lPlan.getPlanId() == planId) lPlan.setPlanState(true);
        }
    }
}
